-- 2022-8-2

--[[10.0
    与其他几种脚本语言不同，Lua语言既没有使用POSIX正则表达式，也没有使用Perl正则表达式来进行模式匹配
    之所以这样的原因是大小问题
    一个典型的POSIX正则表达式需要超过4000行代码，这比Lua语言标准库总大小一半还大
    相比之下 Lua语言模式匹配的实现代码只有不到600行，尽管实现不了POSIX所有功能，但Lua语言的模式匹配仍然非常强大
]]

--[[10.1.0
    字符串标准库提供了基于模式的四个函数，我们已经初步了解过函数find和函数gsub，其余的两个函数分别是match和gmatch(global match)
]]

---[[10.1.1 string.find
    -- 用于在指定的目标字符串中搜索指定的模式。最简单的模式就是一个单词，它只会匹配到这个单词本身
    -- string.find找到一个模式后，会返回两个值：匹配到模式开始位置的索引和结束位置的索引，如果没有找到任何匹配，则返回nil
    do
        local s = "hello world"
        local i,j = string.find(s,"hello")
        print(i,j)
        print(string.sub(s,i,j))
        print(string.find(s,"world"))
        i,j = string.find(s,"l")
        print(i,j)
    end

    -- 模匹配成功后，函数返回的结果为参数调用函数string.sub可以来获取目标字符串在匹配相应模式的子串。对于简单模式来说，这就是模式本身
    -- 函数string.find具有两个可选参数
    -- 第三个参数是一个索引，用于说明从目标字符串的哪个位置开始搜索
    -- 第四个参数是一个布尔值，用于说明是否进行简单搜索
    -- 字如其名，简单搜索就是忽略模式而在目标字符串中进行单纯的"查找字符串"的动作
    do
        --string.find("a [word]","[") -->报错，因为"["在模式中具有特殊含义，因此会报错
        string.find("a [word]","[",1,true) --> 正确查找到，因为开启了简单搜索
    end
--]]

---[[10.1.2 string.match
    -- 由于函数string.match也用于在一个字符串中搜索模式，因此它与函数string.find非常相似
    -- 不过函数string.match返回的是目标字符串中与模式相匹配的那部分子串，而非模式所在的位置
    print(string.match("hello world","hello"))
    -- 对于这样的固定格式使用match函数并没有什么意义，然而当模式是变量是，这个函数的强大之处体现了出来
    do
        local date = "Today is 2022/8/2"
        d = string.match(date,"%d+/%d+/%d+")
        -- https://blog.csdn.net/qq_20336817/article/details/50976494 -- 关于模式匹配中一些参数和特殊符号
        print(d)
    end
--]]

---[[10.1.3 string.gsub
    -- 函数string.gsub有三个必选参数:目标字符串，模式和替换字符串
    -- 其基本用法是将目标字符串中所有出现模式的地方换成替换字符串
    do
        local s = string.gsub("Lua is cute","cute","great")
        print(s)
        s = string.gsub("all lii","l","x")
        print(s)
        s = string.gsub("Lua is great","Sol","Sun")
        print(s)
    end
    -- 此外，该函数还有第四个可选的参数，用于限制替换的次数
    do
        local s = string.gsub("all lii","l","x",1)
        print(s)
        s = string.gsub("all lii","l","x",2)
        print(s)
        s = string.gsub("all lii","l","x",3)
        print(s)
        s = string.gsub("all lii","l","x",4)
        print(s)
    end
    -- 除了替换字符串以外，string.gsub的第三个参数也可以是一个函数或一个表，这个函数或表会被调用(或检索)以产生替换字符串
    -- 此外string.gsub还会返回第二个结果，就是替换次数
--]]

---[[10.1.4 string.gmatch
    -- 函数string.gmatch返回一个函数，通过返回的函数可以遍历一个字符串中所有出现的指定模式
    do
        local s = "some string"
        local words = {}
        for w in string.gmatch(s,"%a+") do
            words[#words+1] = w
        end
        for index, value in ipairs(words) do
            print(index,value)
        end
    end
    -- 模式 %a+ 会匹配一个或多个字母组成的序列(也就是单词)
    -- 因此for循环会遍历所有目标字符串中的单词，然后把它们保存到列表words中
--]]